The Imap control can be used to communicate securely with servers using SSL 2.0, SSL 3.0, TLS, or PCT by setting the Privacy property. Handle server certificate authentication (whether or not to accept the certificate the server sends) in the Authenticate event, or using the Security property in scripted environments with no events. Handle client certificate authentication (when the server requests the client authenticate itself using a certificate) in the Certificate event and using the Certificate property.
The simplest way the Imap control could be used to communicate securely is to set the Security property to secureIgnoreCertificate (which will cause the control to automatically accept any certificate the server sends) and connect to a secure server. This technique, while simple, has obvious security holes that are addressed in the remainder of this topic. Incidentally, for environments that lack events such as ASP, the Security property should always be used to dictate how the control should handle the server's certificate.
Example |
Copy Code |
---|---|
Private Sub SecurityTest1() ' Accept any certificate the server sends, valid or invalid. Imap1.Security = secureIgnoreCertificate ' Set the SSL privacy to use - privacyImplicitAuto works in most cases Imap1.Privacy = privacyImplicitAuto ' Connect and login to a secure Imap server on the standard secure Imap port 993. Imap1.Login "myImapServer", "myAccount", "myPassword", 993 End Sub |
As stated above, disabling security checks is the easiest way to use connect to a secure server but has massive security drawbacks. To remedy this, set the Security property back to secureNormal to perform all certificate checks within the Authenticate event.
Example |
Copy Code |
---|---|
Private Sub SecurityTest2() ' Perform all checks in the Authenticate event Imap1.Security = secureNormal ' Set the SSL privacy to use - privacyImplicitAuto works in most cases Imap1.Privacy = privacyImplicitAuto ' Connect and login to a secure Imap server on the standard secure Imap port 993. Imap1.Login "myImapServer", "myAccount", "myPassword", 993 End Sub Private Sub Imap1_Authenticate(ByVal RemoteCertificate As DartMailCtl.ICertificate, ByVal TrustedRoot As Boolean, ByVal ValidDate As Boolean, ByVal ValidSignature As Boolean, Valid As Boolean) ' The server's certificate has been received. Dim Msg As String ' Check to see if it passed all the checks. If Not Valid Then ' It didn't, so check everything and give the user the option to accept/reject. If Not ValidDate Then Msg = Msg + "- Certificate date is invalid" + vbCrLf If Not TrustedRoot Then Msg = Msg + "- Certificate Authority is not trusted" + vbCrLf If Not ValidSignature Then Msg = Msg + "- Certificate does not contain a valid signature" + vbCrLf Msg = "The following conditions are true:" + vbCrLf + vbCrLf + Msg + vbCrLf + vbCrLf Msg = Msg + "Do you still wish to authenticate?" If MsgBox(Msg, vbYesNo + vbExclamation, "Security Alert") = vbYes Then ' User still wants to accept so accept it (by setting Valid to true) Valid = True End If End If End Sub |
Occasionally, a server may require a client authenticate itself to the server by sending a certificate. If this happens, the Certificate event will fire and the Certificate property must be set to a valid Certificate object. In environments that do not support events, the property can be set before logging in.
The following code demonstrates using a CertificateStore object to select a certificate, although the CertificateList control is useful for this purpose as well (and is demonstrated in most of the installed sample applications).
Note, in order for a client to authenticate themselves, the local machine must have an installed certificate. See the Certificate Manager topic for information on obtaining a certificate.
Example |
Copy Code |
---|---|
Private Sub Imap1_Certificate() ' The server has requested a certificate from the client. Dim Store As New CertificateStore 'Get the certificates in "MY" certificate store located in the 'current user registry key. Store.Name = "MY" Store.Location = locationCurrentUser Store.Refresh ' Check to see if any certificates were found in this store. If Store.Certificates.Count > 0 Then ' Yep. Just use the first one. SecureTcp1.Certificate = Store.Certificates.Item(1) Else ' Uh oh. No client certificate. Authentication will fail. End If End Sub |
In addition to establishing implicitly secure connections to servers on port 993 as demonstrated in the examples above, the control can make explicitly secure connections, if the server supports the STARTTLS command. With explicit security, the control first connects non-securely, then switches to a secure connection. This can be accomplished by setting the Privacy property to privacyExplicitTLS.
Example |
Copy Code |
---|---|
Private Sub ExplicitLogin() ' Accept any certificate the server sends, valid or invalid. Imap1.Security = secureIgnoreCertificate ' Connect non-securely, then switch to TLS Imap1.Privacy = privacyExplicitTLS ' Connect and login to an Imap server on the standard port. Imap1.Login "myImapServer", "myAccount", "myPassword", 143 End Sub |